package org.example.heap;


import java.util.concurrent.TimeUnit;

/**
 * -Xms60M -Xmx60M -XX:-DoEscapeAnalysis -XX:+PrintGCDetails
 * 栈上分配测试
 * 通过  -XX:+DoEscapeAnalysis
 * 1. 添加这个逃逸分析，再频繁分配对象的时候没有进行 GC 操作，说明当前对象没有分配在堆，而是分配在栈上
 * 2. 可以通过 jmap -histo pid 查看当前对象的实例数 77175
 *
 *   -XX:-DoEscapeAnalysis
 * 1. 关闭逃逸分析，之后在分配对象的时候会频繁的触发 GC，说明当前对象是分配在堆中的
 * 2. 通过 jmap -histo pid 查看当前对象的实例数 856152
 * @author youshang
 * @date 2022/03/23 09:22
 **/
public class StackAllocationTest {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();

        for (int i = 0; i < 10000000; i++) {
            //alloc(); //发生了逃逸
            a_method();
        }
        long end = System.currentTimeMillis();
        System.out.println("花费时间：end - start = "+ (end - start));
        try {
            Thread.sleep(10000000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void alloc(){
        User user = new User();
    }
    static class User{
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }



    static User global_v;
    public static void a_method(){
        User v=b_method(); //发生了逃逸
        v.setName("zs");
        c_method();//发生了逃逸
    }

    /**
     * 发生了逃逸
     * @return
     */
    public static User b_method(){
        User v=new User();
        return v;
    }

    /**
     * 发生了逃逸
     */
    public static void c_method() {
        global_v = new User();
    }

}
